package com.weipai.education.service.impl;

import com.weipai.education.config.interceptor.LoginHandlerInterceptor;
import com.weipai.education.dao.*;
import com.weipai.education.enums.PurchaseStatus;
import com.weipai.education.enums.RetCode;
import com.weipai.education.enums.UserType;
import com.weipai.education.model.*;
import com.weipai.education.model.api.PageResult;
import com.weipai.education.model.api.Response;
import com.weipai.education.service.ProductService;
import com.weipai.education.utils.GenerateUserAccountNumberUtils;
import com.weipai.education.utils.OrderNumberUtils;
import com.weipai.education.utils.SessionUserUtil;
import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @Author: 曹朋飞
 * @Date: 2018/12/11 13:27
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private PurchaseDao purchaseDao;
    @Autowired
    private ExchangeDao exchangeDao;
    @Autowired
    private ProductDao productDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private LoginHandlerInterceptor loginHandlerInterceptor;
    @Autowired
    private SessionUserUtil sessionUserUtil;
    @Autowired
    private InventoryDao inventoryDao;
    @Autowired
    private UserCategoryDao userCategoryDao;

    @Override
    public Response list(Integer page, Integer size, Integer key, String productCateId) {

        int tye = loginHandlerInterceptor.getUserType();


        Response response = new Response();
        Integer start = (page - 1) * size;
        List<Map<String, Object>> product = productDao.list(start, size, key, productCateId);
        Integer totalNum = productDao.listAmount(key, productCateId);
        PageResult<Map<String, Object>> pageList = new PageResult<>(product, page, size, totalNum);
        response.setCode(RetCode.SUCCESS);
        response.put("pageList", pageList);
        return response;
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public Response save(Product product, String desc, String productPrice) {
        Response response = new Response();
        ProductDesc productDesc = new ProductDesc();
        JSONArray jsonArray = JSONArray.fromObject(productPrice);//把String转换为json
        List<ProductPrice> productPriceList = JSONArray.toList(jsonArray, new ProductPrice(), new JsonConfig());
        for (ProductPrice price : productPriceList) {
            if (price.getUserCateId() == null) {
                response.setCode(RetCode.NO_USER_CATE_ID);
                return response;
            }
            if (price.getProductPrice() == null) {
                response.setCode(RetCode.NO_PRODUCT_PRICE);
                return response;
            }
        }

        if (null != product.getId()) {
            productDesc = productDao.selectProductDescByProductId(product.getId());
            productDesc.setRemark(desc);
            productDao.updateProduct(product);
            productDao.updateProductDesc(productDesc);

            for (ProductPrice price : productPriceList) {
                price.setProductId(product.getId());
            }
            productDao.updateProductPrice(productPriceList);
        } else {
            product.setSoldOut(0);
            product.setProductNumber(0);
            product.setSpuNumber(GenerateUserAccountNumberUtils.generaateUserAccountNumber());
            product.setUpdateTime(new Date());
            productDao.insertProduct(product);

            productDesc.setRemark(desc).setProductId(product.getId());
            productDao.insertProductDesc(productDesc);

            for (ProductPrice price : productPriceList) {
                price.setProductId(product.getId());
            }
            productDao.insertProductPrice(productPriceList);

            Inventory inventory = new Inventory();
            inventory.setStock(0).setProductId(product.getId()).setUserId(-1);
            inventoryDao.saveInventory(inventory);
        }
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response changeStatus(String id) {
        Response response = new Response();
        Product product = productDao.selectByPrimaryKey(id);
        if (null != product) {
            if (0 == product.getStatus()) {
                product.setStatus(-1);
            } else {
                product.setStatus(0);
            }
            productDao.updateProduct(product);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response getProductInfo(String productId, String userId) {
        Response response = new Response();

        Map<String, Object> productMap = productDao.getProductInfo(productId);

        if (!productMap.isEmpty()) {
            //获取此用户的此商品的价格
            Map<String, Object> priceMap = productDao.getProductPriceByUserId(productId, userId);
            response.put("product", productMap);
            response.put("productPrice", priceMap);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response getInfoByProductId(String productId) {
        Response response = new Response();
        Map<String, Object> productMap = productDao.getProductInfo(productId);
        if (!productMap.isEmpty()) {
            //获取商品的价格
            List<Map<String, Object>> priceMap = productDao.getProductPrice(productId);
            response.put("product", productMap);
            response.put("productPrice", priceMap);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response getAllGoodsBar(Integer productId, String type) {
        Response response = new Response();

        List<Map<String, Object>> goodsBarList = productDao.getAllGoodsBar(productId, type);
        if (goodsBarList != null) {
            response.setCode(RetCode.SUCCESS);
            response.setData(goodsBarList);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response getProductPriceByProductCateIdAndUserId(Integer productCateId) {
        Response response = new Response();

        //从session中获取userId 
        String userId = sessionUserUtil.getUser().getId().toString();

        User user = userDao.selectByPrimaryKey(userId);
        List<Map<String, Object>> productList = productDao.getProductPriceByProductCateIdAndUserCateId(productCateId, user.getUserCateId());
        if (productList != null) {
            response.setCode(RetCode.SUCCESS);
            response.setData(productList);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response allProduct(String userId) {
        Response response = new Response();
        User user = userDao.selectByPrimaryKey(userId);
        Integer userCateId = user.getUserCateId();
        if (user.getUserCateId() == null) {
            UserCategory userCategory = userCategoryDao.getUserCateInfo();
            userCateId = userCategory.getId();
        }
        List<Map<String, Object>> productList = productDao.getProductPriceByProductCateIdAndUserCateId(null, userCateId);
        if (productList != null) {
            response.setCode(RetCode.SUCCESS);
            response.setData(productList);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response getProductBySpuNumber(String spuNumber) {
        Response response = new Response();
        List<Map<String, Object>> productList = productDao.getProductBySpuNumber(spuNumber);
        if (null != productList) {
            response.setCode(RetCode.SUCCESS);
            response.setData(productList);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response exchange(ExchangeMessage exchangeMsg) {
        Response response = new Response();
        //从session中获得userIdf
        String userId = sessionUserUtil.getUser().getId().toString();
        List<Integer> inventoryDetailId = new ArrayList<>();
        List<Map<String, Integer>> inventoryDetailInfo = new ArrayList<>();
        String PurchaseNumber = OrderNumberUtils.outTradeNo();
        User exchangeUser = userDao.getUserByMobile(exchangeMsg.getInventoryNumber()); //此处手机号
        if ("1".equals(exchangeMsg.getIsHeadset())) { //需要货号，有换货号，是条码号
            String[] fields = exchangeMsg.getBarCode().split(",");
//            //现有库存
//            Inventory inventory = inventoryDao.getInventory("-1", exchangeMsg.getProductId());
//            if (inventory == null || inventory.getStock() < fields.length) {
//                response.setCode(RetCode.UNDER_STOCK);
//                return response;
//            }
            if ("1".equals(exchangeMsg.getRemark())) {  //换货的
                //check换货单号
                Exchange exchange = exchangeDao.selectExchangeByExchangeNumber(exchangeMsg.getPurchaseNumber());
                if (exchange == null) {  //换货单号未找到
                    response.setCode(RetCode.NOT_DATA);
                    return response;
                }
                if (exchange.getProductNumber() != fields.length) {  //换货申请数量与货号不一致
                    response.setCode(RetCode.NO_AGREEMENT);
                    return response;
                }
                Purchase purchase = purchaseDao.getPurchaseByPurchaseNumber(exchange.getPurchaseNumber());//根据订单id搜订单信息

                for (String goodsBarCode : fields) {
                    //根据userId和goodsBarCode查询此账户下是否有这个商品
                    InventoryDetail inventoryDetail = inventoryDao.getInventoryDetail("-1", exchangeMsg.getProductId(), goodsBarCode);
                    if (null == inventoryDetail) {
                        response.setCode(RetCode.NOT_DATA);
                        response.put("goodsBarCode", "未找到[" + goodsBarCode + "]商品");
                        return response;
                    }
                    Map<String, Integer> tempMap = new HashMap<>();
                    tempMap.put("isPrice", inventoryDetail.getIsPrice());
                    tempMap.put("isDamage", inventoryDetail.getIsDamage());
                    inventoryDetailInfo.add(tempMap);
                    inventoryDetailId.add(inventoryDetail.getId());
                }

                //添加一条订单 没有快递和快递单号
                Purchase purchase1 = new Purchase();
                purchase1.setStatus(PurchaseStatus.HAVE_OUTBOUND.getType()).setDhl(purchase.getDhl()).setExpressNumber(purchase.getExpressNumber()).setDeliveryTime(new Date()).setIsExchage(1).setDeliverUserId(-1).setReceiveUserId(exchangeUser.getId()).setMobile(purchase.getMobile()).setProductId(Integer.valueOf(exchangeMsg.getProductId())).setName(purchase.getName()).setUserAddressId(purchase.getUserAddressId()).setUserAddress(purchase.getUserAddress()).setProductNumber(fields.length).setProductPrice(purchase.getProductPrice()).setPurchaseMoney(purchase.getProductPrice().multiply(BigDecimal.valueOf(fields.length))).setPurchaseNumber(PurchaseNumber);
                purchaseDao.insert(purchase1);
            } else if ("2".equals(exchangeMsg.getRemark()) || "3".equals(exchangeMsg.getRemark())) {  //奖励
                for (String goodsBarCode : fields) {
                    //根据userId和goodsBarCode查询此账户下是否有这个商品
                    InventoryDetail inventoryDetail = inventoryDao.getInventoryDetail("-1", exchangeMsg.getProductId(), goodsBarCode);
                    if (null == inventoryDetail) {
                        response.setCode(RetCode.NOT_DATA);
                        response.put("goodsBarCode", "未找到[" + goodsBarCode + "]商品");
                        return response;
                    }
                    Map<String, Integer> tempMap = new HashMap<>();
                    tempMap.put("isPrice", inventoryDetail.getIsPrice());
                    tempMap.put("isDamage", inventoryDetail.getIsDamage());
                    inventoryDetailInfo.add(tempMap);
                    inventoryDetailId.add(inventoryDetail.getId());
                }
                //添加一条订单 没有快递和快递单号
                //退货的那条订单
                Purchase purchase1 = new Purchase();
                if (exchangeMsg.getPurchaseNumber() != null && !exchangeMsg.getPurchaseNumber().isEmpty()) {
                    Purchase purchase = purchaseDao.getPurchaseByPurchaseNumber(exchangeMsg.getPurchaseNumber());//根据订单id搜订单信息
                    purchase1.setStatus(PurchaseStatus.HAVE_OUTBOUND.getType())
                            .setDhl(purchase.getDhl())
                            .setExpressNumber(purchase.getExpressNumber())
                            .setIsExchage(1)
                            .setDeliverUserId(-1)
                            .setReceiveUserId(exchangeUser.getId())
                            .setMobile(purchase.getMobile())
                            .setProductId(Integer.valueOf(exchangeMsg.getProductId()))
                            .setName(purchase.getName())
                            .setUserAddressId(purchase.getUserAddressId())
                            .setUserAddress(purchase.getUserAddress())
                            .setProductNumber(fields.length)
                            .setProductPrice(purchase.getProductPrice())
                            .setPurchaseMoney(purchase.getProductPrice().multiply(BigDecimal.valueOf(fields.length)))
                            .setPurchaseNumber(PurchaseNumber);
                } else {
                    Map<String, Object> productInfo = productDao.getProductPriceByUserId(exchangeMsg.getProductId(), Integer.toString(exchangeUser.getId()));
                    BigDecimal ProductPrice = (BigDecimal) productInfo.get("product_price");
                    purchase1.setStatus(PurchaseStatus.HAVE_OUTBOUND.getType()).setDhl("").setExpressNumber("").setDeliveryTime(new Date()).setIsExchage(1).setDeliverUserId(-1).setReceiveUserId(exchangeUser.getId()).setMobile("").setProductId(Integer.valueOf(exchangeMsg.getProductId())).setName("").setUserAddressId(0).setUserAddress("").setProductNumber(fields.length).setProductPrice(ProductPrice).setPurchaseMoney(ProductPrice.multiply(BigDecimal.valueOf(fields.length))).setPurchaseNumber(PurchaseNumber);
                }

                purchaseDao.insert(purchase1);
            } else {
                response.setCode(RetCode.REQUEST_ERROR);
                return response;
            }

            for (String goodsBarCode : fields) {
                PurchaseDetail purchaseDetail = new PurchaseDetail();
                purchaseDetail.setGoodsBarCode(goodsBarCode).setPurchaseNumber(PurchaseNumber);
                purchaseDao.insertProductDetail(purchaseDetail);
            }

            //减库存
            Inventory inventoryDel = inventoryDao.getInventory("-1", exchangeMsg.getProductId());
            inventoryDel.setStock(inventoryDel.getStock() - fields.length);
            inventoryDao.updateByPrimaryKeySelective(inventoryDel);

            //fields的商品从我的推荐人库中删除
            inventoryDao.batchDeleteInventoryDetailById(inventoryDetailId);

            //出库记录
            InventoryOut out = new InventoryOut();
            String outOrderNumber = OrderNumberUtils.outTradeNo();
            out.setPurchaseNumber(PurchaseNumber).setOutOrderNumber(outOrderNumber)
                    .setDeliverUserId(-1).setProductId(Integer.parseInt(exchangeMsg.getProductId()))
                    .setProductNumber(fields.length).setReceiveUserId(exchangeUser.getId()).setStatus(0);
            inventoryDao.saveInventoryOut(out);

//                出库记录明细
            for (int i = 0; i <= fields.length - 1; i++) {
                InventoryOutDetail inventoryOutDetail = new InventoryOutDetail();
                inventoryOutDetail.setOutOrderNumber(outOrderNumber).setGoodsBarCode(fields[i]).setIsDamage(inventoryDetailInfo.get(i).get("isDamage")).setIsPrice(inventoryDetailInfo.get(i).get("isPrice"));
                inventoryDao.saveInventoryOutDetail(inventoryOutDetail);
            }

            if ("3".equals(exchangeMsg.getRemark())) { //其他的话分奖励
                if (exchangeUser.getSuperiorId() != -1) {  //-1表示上级是后台账号 发单的人的上级不是平台账号
                    //发单人的推荐人
                    User referrerUser = userDao.selectByPrimaryKey(Integer.toString(exchangeUser.getReferrerId()));

                    //推荐人总部账号，是总部直接开通的，不走分润
                    if (referrerUser.getType() == UserType.SELL_USER.getType()) {
                        //推荐后期拿货奖励
                        PurchaseServiceImpl purchaseService = new PurchaseServiceImpl();
                        purchaseService.recommendGoodsReward(exchangeUser, PurchaseNumber);
                        //区域 后期拿货奖励
                        purchaseService.areaGoodsReward(exchangeUser, PurchaseNumber);
                    }
                }
            }
            response.setCode(RetCode.SUCCESS);
        } else { //不需要货号
            Integer inventoryNum = Integer.parseInt(exchangeMsg.getNumber());
            //现有库存
            Inventory inventory = inventoryDao.getInventory("-1", exchangeMsg.getProductId());
            if (inventory == null || inventory.getStock() < inventoryNum) {
                response.setCode(RetCode.UNDER_STOCK);
                return response;
            }
            if ("1".equals(exchangeMsg.getRemark())) {

                Exchange exchange = exchangeDao.selectExchangeByExchangeNumber(exchangeMsg.getPurchaseNumber());
                if (exchange == null) {  //换货单号未找到
                    response.setCode(RetCode.NOT_DATA);
                    return response;
                }
                if (exchange.getProductNumber() != inventoryNum) {  //换货申请数量与货号不一致
                    response.setCode(RetCode.NO_AGREEMENT);
                    return response;
                }

                //这里获取要删除的id
                List<Map<String, Integer>> product = inventoryDao.selectDetailPeoduct(Integer.valueOf(exchangeMsg.getProductId()), -1, inventoryNum);

                if (!product.isEmpty()) {
                    for (Map<String, Integer> map : product) {
                        inventoryDetailId.add(map.get("id"));
                        Map<String, Integer> tempMap = new HashMap<>();
                        tempMap.put("isPrice", map.get("is_price"));
                        tempMap.put("isDamage", map.get("is_damage"));
                        inventoryDetailInfo.add(tempMap);
                    }
                }
                inventoryDao.batchDeleteInventoryDetailById(inventoryDetailId);

                Purchase purchase = purchaseDao.getPurchaseByPurchaseNumber(exchange.getPurchaseNumber());//根据订单id搜订单信息
                Purchase purchase1 = new Purchase();
                purchase1.setStatus(PurchaseStatus.HAVE_OUTBOUND.getType()).setDhl(purchase.getDhl()).setExpressNumber(purchase.getExpressNumber()).setDeliveryTime(new Date()).setIsExchage(1).setDeliverUserId(-1).setReceiveUserId(exchangeUser.getId()).setMobile(purchase.getMobile()).setProductId(Integer.valueOf(exchangeMsg.getProductId())).setName(purchase.getName()).setUserAddressId(purchase.getUserAddressId()).setUserAddress(purchase.getUserAddress()).setProductNumber(inventoryNum).setProductPrice(purchase.getProductPrice()).setPurchaseMoney(purchase.getProductPrice().multiply(BigDecimal.valueOf(inventoryNum))).setPurchaseNumber(PurchaseNumber);
                purchaseDao.insert(purchase1);
            } else if ("2".equals(exchangeMsg.getRemark()) || "3".equals(exchangeMsg.getRemark())) {

                //添加一条订单 没有快递和快递单号
                Purchase purchase1 = new Purchase();
                if (exchangeMsg.getPurchaseNumber() != null) {
                    Purchase purchase = purchaseDao.getPurchaseByPurchaseNumber(exchangeMsg.getPurchaseNumber());//根据订单id搜订单信息
                    purchase1.setStatus(PurchaseStatus.HAVE_OUTBOUND.getType()).setDhl(purchase.getDhl()).setExpressNumber(purchase.getExpressNumber()).setDeliveryTime(new Date()).setIsExchage(1).setDeliverUserId(-1).setReceiveUserId(exchangeUser.getId()).setMobile(purchase.getMobile()).setProductId(Integer.valueOf(exchangeMsg.getProductId())).setName(purchase.getName()).setUserAddressId(purchase.getUserAddressId()).setUserAddress(purchase.getUserAddress()).setProductNumber(inventoryNum).setProductPrice(purchase.getProductPrice()).setPurchaseMoney(purchase.getProductPrice().multiply(BigDecimal.valueOf(inventoryNum))).setPurchaseNumber(PurchaseNumber);
                } else {
                    Map<String, Object> productInfo = productDao.getProductPriceByUserId(exchangeMsg.getProductId(), Integer.toString(exchangeUser.getId()));
                    BigDecimal ProductPrice = (BigDecimal) productInfo.get("product_price");
                    purchase1.setStatus(PurchaseStatus.HAVE_OUTBOUND.getType()).setDhl("").setExpressNumber("").setDeliveryTime(new Date()).setIsExchage(1).setDeliverUserId(-1).setReceiveUserId(exchangeUser.getId()).setMobile("").setProductId(Integer.valueOf(exchangeMsg.getProductId())).setName("").setUserAddressId(0).setUserAddress("").setProductNumber(inventoryNum).setProductPrice(ProductPrice).setPurchaseMoney(ProductPrice.multiply(BigDecimal.valueOf(inventoryNum))).setPurchaseNumber(PurchaseNumber);
                }

                purchaseDao.insert(purchase1);

            } else {
                response.setCode(RetCode.REQUEST_ERROR);
                return response;
            }
            for (Integer i = 0; i < inventoryNum; i++) {
                PurchaseDetail purchaseDetail = new PurchaseDetail();
                purchaseDetail.setGoodsBarCode("").setPurchaseNumber(PurchaseNumber);
                purchaseDao.insertProductDetail(purchaseDetail);
            }
            //减库存
            Inventory inventoryDel = inventoryDao.getInventory("-1", exchangeMsg.getProductId());
            inventoryDel.setStock(inventoryDel.getStock() - inventoryNum);
            inventoryDao.updateByPrimaryKeySelective(inventoryDel);

            //fields的商品从我的推荐人库中删除
            inventoryDao.batchDeleteInventoryDetailById(inventoryDetailId);

            //出库记录
            InventoryOut out = new InventoryOut();
            String outOrderNumber = OrderNumberUtils.outTradeNo();
            out.setPurchaseNumber(PurchaseNumber).setOutOrderNumber(outOrderNumber)
                    .setDeliverUserId(-1).setProductId(Integer.parseInt(exchangeMsg.getProductId()))
                    .setProductNumber(inventoryNum).setReceiveUserId(exchangeUser.getId()).setStatus(0);
            inventoryDao.saveInventoryOut(out);

//                出库记录明细
            for (int i = 0; i < inventoryNum; i++) {
                InventoryOutDetail inventoryOutDetail = new InventoryOutDetail();
                inventoryOutDetail.setOutOrderNumber(outOrderNumber).setGoodsBarCode("").setIsDamage(inventoryDetailInfo.get(i).get("isDamage")).setIsPrice(inventoryDetailInfo.get(i).get("isPrice"));
                inventoryDao.saveInventoryOutDetail(inventoryOutDetail);
            }
            response.setCode(RetCode.SUCCESS);
        }
        return response;
    }

    @Override
    public Response getUserGoodsBar(Integer productId) {
        Response response = new Response();

        //从session中获取userId 
        String userId = sessionUserUtil.getUser().getId().toString();
        User user = userDao.selectByPrimaryKey(userId);
        if (user.getType() == UserType.HQ_USER.getType()) {
            userId = "-1";
        }
        List<Map<String, Object>> productList = inventoryDao.getUserGoodsBar(productId, userId);
        if (null != productList) {
            response.setCode(RetCode.SUCCESS);
            response.setData(productList);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }
}
